home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 52
/
Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso
/
Aminet
/
util
/
moni
/
Scout-src.lha
/
source
/
scout_net.c
< prev
next >
Wrap
C/C++ Source or Header
|
2002-09-16
|
20KB
|
717 lines
/**
* Scout - The Amiga System Monitor
*
*------------------------------------------------------------------
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* You must not use this source code to gain profit of any kind!
*
*------------------------------------------------------------------
*
* @author Andreas Gelhausen
* @author Richard Körber <rkoerber@gmx.de>
*/
#include "system_headers.h"
extern APTR AP_Scout;
extern STRPTR _ProgramName;
/********************************************************************/
/* Benötigte Prototypes */
/********************************************************************/
#define NAMELEN 32
#define LINELEN 82
#define TRENNCHAR '\0'
UBYTE *CMD_BEGIN = "BEGIN";
UBYTE *CMD_USER = "USER";
UBYTE *CMD_PASSWORD = "PASSWORD";
UBYTE *CMD_END = "END";
UBYTE *CMD_DONE = "DONE";
UBYTE *CMD_ERROR = "ERROR";
UBYTE *CMD_CONNECTED = "CONNECTED";
static struct RDArgs *rdargs;
static struct RDArgs *myrdargs;
static int server_socket = -1;
static int client_socket = -1;
static int connected = FALSE;
static long type = SOCK_STREAM;
static long sinlen;
static struct sockaddr_in sin;
BOOL clientstate = FALSE;
BOOL serverstate = FALSE;
BOOL shellstate = FALSE;
char username[10+1];
char password[_PASSWORD_LEN+1];
void failtcp( void )
{
if (client_socket >= 0) {
if (connected) shutdown(client_socket, 2);
CloseSocket(client_socket);
}
if (UserGroupBase) CloseLibrary(UserGroupBase);
if (SocketBase) CloseLibrary(SocketBase);
}
int inittcp( void )
{
if (!(SocketBase = OpenLibrary("bsdsocket.library", 4L))) return FALSE;
if (!(UserGroupBase = OpenLibrary("usergroup.library", 4))) return FALSE;
return TRUE;
}
static int sgetc( int sock )
{
unsigned char c;
fd_set rd,ex;
ULONG flgs;
int n;
struct timeval t;
t.tv_sec = 10L;
t.tv_usec = 0;
FD_ZERO(&rd);
FD_ZERO(&ex);
FD_SET(sock,&rd);
FD_SET(sock,&ex);
if (clientstate) {
flgs = 0;
WaitSelect(16,&rd,0L,&ex,&t,&flgs);
} else {
flgs = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D;
WaitSelect(16,&rd,0L,&ex,NULL,&flgs);
}
if (FD_ISSET(sock,&rd)) {
n = recv(sock, &c, 1, 0);
if (n == 1) {
return c;
} else {
return -1;
}
} else {
return -1;
}
}
int sgets( int sock,
char *string,
int maxchars )
{
int nchars = 0;
char c;
while (nchars < maxchars && (c = sgetc(sock)) != EOF && c != TRENNCHAR) {
string[nchars] = c;
nchars++;
}
string[nchars] = '\0';
return nchars;
}
static char NetHelpText[] = "\n" \
" Available lists:\n" \
" ----------------\n" \
" Allocations Assigns BoopsiClasses Commands\n" \
" Commodities Devices Expansions Fonts\n" \
" InputHandlers Interrupts Libraries Locks\n" \
" LowMemory Memory Mounts Ports\n" \
" Residents Resources ScreenMode Semaphores\n" \
" System Tasks Timer Vectors\n" \
" Windows\n\n" \
" Other commands:\n" \
" ---------------\n" \
" Help";
void PrintNetHelp( void )
{
if (serverstate || shellstate) {
int i = 0;
UBYTE *tmp;
if (tmp = AllocVec(256, MEMF_ANY)) {
SendResultString(NetHelpText);
while (arexx_list[i].mc_Name) {
strcpy(tmp, " ");
strcat(tmp, arexx_list[i].mc_Name);
if (arexx_list[i].mc_Parameters) {
strcat (tmp, " ");
strcat (tmp, arexx_list[i].mc_Template);
}
SendResultString(tmp);
i++;
}
FreeVec(tmp);
}
}
}
/*
** Dieser Hook wird benötigt um die ARexx-Command-Liste für
** die TCP_Befehle nutzen zu können!
*/
struct NetHook {
struct MinNode h_egal1;
__asm ULONG (*h_Entry) (register __a1 ULONG *);
ULONG (*h_egal2)();
APTR h_egal3;
};
struct Net_Command {
char *nc_Name;
void (*nc_func)(char *);
};
struct Net_Command net_list[] = {
"Allocations", PrintAllocations,
"Assigns", PrintAssigns,
"BoopsiClasses", PrintClass,
"Commands", PrintCommands,
"Commodities", PrintCx,
"Devices", PrintDevices,
"Expansions", PrintExpansions,
"Fonts", PrintFonts,
"InputHandlers", PrintInputHandlers,
"Interrupts", PrintInterrupts,
"Libraries", PrintLibraries,
"LowMemory", PrintLowMemory,
"Memory", PrintMemory,
"Mounts", PrintMounts,
"Locks", PrintLocks,
"Ports", PrintPorts,
"Residents", PrintResidents,
"ScreenMode", PrintSMode,
"Semaphores", PrintSemaphores,
"System", PrintSystem,
"Tasks", PrintTasks,
"Timer", PrintTimer,
"Resources", PrintResources,
"Vectors", PrintVectors,
"Windows", PrintWindows,
"Patches", PrintPatches,
"Catalogs", PrintCatalogs,
"AudioModes", PrintAudioModes,
"ResetHandlers", PrintResetHandlers,
"Help", (void (* ) (char *)) PrintNetHelp,
"a", PrintAllocations,
"b", PrintClass,
"c", PrintCommands,
"d", PrintDevices,
"e", PrintTimer,
"f", PrintFonts,
"g", PrintAssigns,
"h", PrintInputHandlers,
"i", PrintInterrupts,
"j", PrintLowMemory,
"k", PrintCx,
"l", PrintLibraries,
"m", PrintMemory,
"n", PrintMounts,
"o", PrintLocks,
"p", PrintPorts,
"r", PrintResidents,
"s", PrintSemaphores,
"t", PrintTasks,
"u", PrintResources,
"v", PrintVectors,
"w", PrintWindows,
"x", PrintExpansions,
"y", PrintSystem,
"z", PrintSMode,
"GetAlcList", (void (* ) (char *))SendAlcList,
"GetAssList", (void (* ) (char *))SendAssList,
"GetClassList", (void (* ) (char *))SendClassList,
"GetComList", (void (* ) (char *))SendComList,
"GetCxList", (void (* ) (char *))SendCxList,
"GetDevList", (void (* ) (char *))SendDevList,
"GetExpList", (void (* ) (char *))SendExpList,
"GetFontList", (void (* ) (char *))SendFontList,
"GetInputList", (void (* ) (char *))SendInputList,
"GetIntList", (void (* ) (char *))SendIntList,
"GetLibList", (void (* ) (char *))SendLibList,
"GetLockList", (void (* ) (char *))SendLockList,
"GetLowMemList", (void (* ) (char *))SendLowMemory,
"GetMemList", (void (* ) (char *))SendMemList,
"GetMountList", (void (* ) (char *))SendMountList,
"GetPortList", (void (* ) (char *))SendPortList,
"GetResList", (void (* ) (char *))SendResList,
"GetResiList", (void (* ) (char *))SendResiList,
"GetSemList", (void (* ) (char *))SendSemList,
"GetSModeList", (void (* ) (char *))SendSModeList,
"GetSysList", (void (* ) (char *))SendSystemList,
"GetTaskList", (void (* ) (char *))SendTaskList,
"GetTimerList", (void (* ) (char *))SendTimerList,
"GetVectorList", (void (* ) (char *))SendVectorList,
"GetWinList", (void (* ) (char *))SendWinList,
"GetPatchList", (void (* ) (char *))SendPatchList,
"GetCatalogList", (void (* ) (char *))SendCatalogList,
"GetAudioModeList", (void (* ) (char *))SendAudioModeList,
"GetResetHandlerList", (void (* ) (char *))SendResetHandlersList,
NULL
};
/********************************************************************/
/* Client */
/********************************************************************/
int SendDaemon( UBYTE *fmt, ... )
{
int result = FALSE;
UBYTE *buf;
if (buf = tbAllocVecPooled(globalPool, LINELEN)) {
va_list args;
va_start(args,fmt);
_vsnprintf(buf, LINELEN, fmt, args);
va_end (args);
if (send(client_socket, buf, strlen(buf) + 1, 0) == strlen(buf) + 1) {
result = TRUE;
}
tbFreeVecPooled(globalPool, buf);
}
return result;
}
static ULONG NetCommand( UBYTE *text )
{
ULONG rc = RETURN_FAIL;
UBYTE *buf;
if (buf = tbAllocVecPooled(globalPool, LINELEN)) {
if (send(client_socket, text, strlen(text) + 1, 0) == strlen(text) + 1) {
while (sgets(client_socket, buf, LINELEN)) {
if (strcmp(buf, CMD_DONE) == 0) {
rc = RETURN_OK;
break;
} else if (strcmp(buf, CMD_ERROR) == 0) {
break;
}
}
}
tbFreeVecPooled(globalPool, buf);
}
return rc;
}
BOOL ReceiveDecodedEntry( UBYTE *structure,
ULONG length )
{
BOOL rc = FALSE;
if (sgets(client_socket, structure, length)) {
if (strcmp(structure, CMD_ERROR) != 0 && strcmp(structure, CMD_DONE) != 0) {
ULONG i = 0;
while (i < length - 1) {
if (structure[i] == '\1') structure[i] = '\0';
i++;
}
rc = TRUE;
}
}
return rc;
}
int ConnectToServer( void )
{
UBYTE hostname[NAMELEN];
UBYTE buffer[LINELEN+2];
struct hostent *host;
struct sockaddr_in server;
if (!inittcp()) {
aprintf(msgCantInitTCPIP);
return FALSE;
}
if (opts.User) {
stccpy(username, opts.User, sizeof(username));
} else {
stccpy(username, getlogin(), sizeof(username));
}
if (opts.Password) {
stccpy(password, opts.Password, sizeof(password));
} else {
stccpy(password, getpass(msgAskForPassword), sizeof(password));
if (password[0] == '\0') {
aprintf(msgCantGetPassword);
return FALSE;
}
}
gethostname(hostname, sizeof(hostname));
if (host = gethostbyname(opts.Host)) {
bzero((char *)&server, sizeof(server));
server.sin_port = 6543;
bcopy(host->h_addr, (char *)&server.sin_addr, host->h_length);
server.sin_family = host->h_addrtype;
client_socket = socket(AF_INET, type, 0);
if (client_socket >= 0) {
if (connect (client_socket, (struct sockaddr *) &server, sizeof (server)) != -1) {
connected = TRUE;
if (SendDaemon(CMD_BEGIN)) {
if (SendDaemon("%s %s", CMD_USER, username) && SendDaemon("%s %s", CMD_PASSWORD, password)) {
if (sgets(client_socket, buffer, LINELEN) && strcmp(buffer, CMD_CONNECTED) != 0) {
aprintf(buffer);
} else {
return TRUE;
}
}
}
} else {
aprintf(msgCantConnectToServer);
}
} else {
aprintf(msgCantCreateSocket);
}
} else {
aprintf(msgCantFindHost, opts.Host);
}
return FALSE;
}
ULONG netshellclient( void )
{
ULONG rc = RETURN_FAIL;
UBYTE recvbuffer[LINELEN+2];
if (clientstate = ConnectToServer()) {
if (SendDaemon("%s ", opts.Command)) {
while (sgets(client_socket, recvbuffer, LINELEN) && strcmp(recvbuffer, CMD_ERROR) != 0 && strcmp(recvbuffer, CMD_DONE) != 0) {
aprintf(recvbuffer);
}
if (strcmp(recvbuffer, CMD_DONE) == 0) {
rc = RETURN_OK;
} else {
rc = RETURN_ERROR;
}
SendDaemon(CMD_END);
}
}
return rc;
}
/********************************************************************/
/* Daemon */
/********************************************************************/
int isNetCall (void) {
int rc = TRUE;
if (! inittcp()) {
return (FALSE);
}
server_socket = init_inet_daemon();
if (server_socket >= 0) {
set_socket_stdio (server_socket);
sinlen = sizeof (sin);
if (getpeername (0, (struct sockaddr *) &sin, &sinlen) == -1) {
// logprint ("scout: getpeername() failed\n");
rc = FALSE;
}
} else {
// logprint ("scout: init_inet_daemon() failed\n");
rc = FALSE;
}
return (rc);
}
int isCommand (char *buffer, char *command) {
int len = strlen (command);
int rc = FALSE;
if ((strnicmp (buffer, command, len) == 0) \
&& ((isspace (buffer[len])) || (buffer[len] == '\0'))) {
rc = len + 1;
}
return (rc);
}
int SendClient (char *fmt, ...)
{
int result = FALSE;
UBYTE *buf;
if (buf = tbAllocVecPooled(globalPool, TMP_STRING_LENGTH)) {
va_list args;
va_start(args,fmt);
_vsnprintf(buf, TMP_STRING_LENGTH, fmt, args);
if (send(0, buf, strlen(buf) + 1, 0) == strlen(buf) + 1) {
result = TRUE;
}
va_end(args);
tbFreeVecPooled(globalPool, buf);
}
return result;
}
BOOL SendEncodedEntry( UBYTE *structure, ULONG length )
{
ULONG i = 0;
while (i < length - 1) {
if (structure[i] == '\0') structure[i] = '\1';
i++;
}
if (SendClient(structure)) {
return FALSE;
}
return TRUE;
}
long SendResultString( UBYTE *fmt, ... )
{
UBYTE *buf;
if (buf = tbAllocVecPooled(globalPool, TMP_STRING_LENGTH)) {
va_list args;
va_start(args, fmt);
_vsnprintf(buf, TMP_STRING_LENGTH, fmt, args);
if (serverstate) {
strcat(buf, "\n");
SendClient(buf);
} else if (shellstate) {
strcat(buf, "\n");
Printf(buf);
} else {
set(AP_Scout, MUIA_Application_RexxString, buf);
}
va_end (args);
tbFreeVecPooled(globalPool, buf);
}
return (TRUE);
}
void PrintFOneLine( BPTR hd,
UBYTE *fmt, ... )
{
UBYTE *buf;
if (buf = tbAllocVecPooled(globalPool, TMP_STRING_LENGTH)) {
va_list args;
va_start(args, fmt);
_vsnprintf(buf, TMP_STRING_LENGTH, fmt, args);
va_end(args);
if (serverstate) {
SendClient(buf);
} else {
Write(hd, buf, strlen(buf));
}
tbFreeVecPooled(globalPool, buf);
}
}
ULONG ExecuteCommand (char *text) {
ULONG rc = RETURN_OK;
char buffer[256];
int i, len;
#define CMDOPT_TEMPLATE "CMD1/A"
#define CMDOPT_COUNT 4
LONG cmdopts[CMDOPT_COUNT];
_snprintf(buffer, sizeof(buffer), "%s ", text);
i = 0;
while (arexx_list[i].mc_Name) {
if (len = isCommand (buffer, arexx_list[i].mc_Name)) {
if (myrdargs = AllocDosObject (DOS_RDARGS,NULL)) {
myrdargs->RDA_Source.CS_Buffer = buffer + len;
myrdargs->RDA_Source.CS_Length = strlen (buffer) - len;
if ((arexx_list[i].mc_Parameters && (rdargs = ReadArgs (arexx_list[i].mc_Template, (LONG *) &cmdopts, myrdargs))) \
|| (!arexx_list[i].mc_Parameters)) {
rc = (*((struct NetHook *) arexx_list[i].mc_Hook)->h_Entry) ((ULONG *) &cmdopts[0]);
FreeArgs (rdargs);
} else {
Fault (IoErr(), NULL, (char *) buffer, LINELEN);
SendResultString (buffer);
rc = RETURN_FAIL;
}
FreeDosObject (DOS_RDARGS,myrdargs);
}
break;
}
i++;
}
if (! (arexx_list[i].mc_Name)) {
i = 0;
while (net_list[i].nc_Name) {
if (len = isCommand (buffer, net_list[i].nc_Name)) {
if (myrdargs = AllocDosObject (DOS_RDARGS,NULL)) {
myrdargs->RDA_Source.CS_Buffer = buffer;
myrdargs->RDA_Source.CS_Length = strlen (buffer);
if (rdargs = ReadArgs (CMDOPT_TEMPLATE, (LONG *) &cmdopts, myrdargs)) {
(*net_list[i].nc_func) (NULL);
FreeArgs (rdargs);
} else {
Fault (IoErr(), NULL, (char *) buffer, LINELEN);
SendResultString (buffer);
rc = RETURN_FAIL;
}
FreeDosObject (DOS_RDARGS,myrdargs);
}
break;
}
i++;
}
if (! (net_list[i].nc_Name)) {
SendResultString(msgUnknownOption);
rc = RETURN_FAIL;
}
}
return (rc);
}
ULONG netdaemon (VOID) {
ULONG rc = TRUE;
char buffer[LINELEN+2];
int len, done = FALSE;
struct passwd *pw, *rootpw;
long rootid = 0;
/*
** inittcp() wurde bereits durch isNetCall() aufgerufen!
*/
serverstate = TRUE;
if (rootpw = getpwnam ("root"))
rootid = rootpw->pw_gid;
if ((sgets (0, buffer, LINELEN)) && (strcmp (buffer, CMD_BEGIN) == 0)) {
//logprint ("BEGIN\n");
if ((sgets (0, buffer, LINELEN)) && (len = isCommand (buffer, CMD_USER)) \
&& (pw = getpwnam (buffer + len))) {
//logprint ("USER %s\n", buffer + len);
if (((rootpw) && (rootid == pw->pw_gid)) || (! rootpw)) {
if ((sgets (0, buffer, LINELEN)) && (len = isCommand (buffer, CMD_PASSWORD))
&& (strcmp (crypt (buffer + len, pw->pw_passwd), pw->pw_passwd) == 0)) {
//logprint ("PASSWORD %s\n", buffer + len);
if (SendClient (CMD_CONNECTED)) {
//logprint ("'CONNECTED' send!\n");
while (sgets (0, buffer, LINELEN)) {
//logprint ("COMMAND '%s'\n", buffer);
if (strcmp (buffer, CMD_END) == 0) {
break;
}
if (ExecuteCommand (buffer)) {
SendClient (CMD_ERROR);
} else {
SendClient (CMD_DONE);
}
done = TRUE;
}
}
} else {
SendClient(msgWrongPassword);
}
} else {
SendClient(msgNoPrivilege);
}
} else {
SendClient(msgUnknownUser);
}
} else {
SendClient(msgNoBEGINReceived);
}
if (! done)
SendClient (CMD_ERROR);
serverstate = FALSE;
return (rc);
}
int MyDoCommand (char *fmt, ...) {
int result = FALSE;
char buf[LINELEN];
va_list args;
va_start(args,fmt);
_vsnprintf(buf, LINELEN, fmt, args);
if (clientstate) {
if (! NetCommand (buf))
result = TRUE;
} else {
if (! ExecuteCommand (buf))
result = TRUE;
}
if (! result) {
MyRequest (msgErrorContinue, msgErrorOccured);
}
va_end (args);
return (result);
}